﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.ComponentModel;
using RemoteTestRunner.Contracts;
using System.Collections.ObjectModel;
using System.Windows.Input;

namespace RemoteTestRunner.BusinessLogic.ViewModels
{
    public class ProjectAdminViewModel : IViewModelBase, INotifyPropertyChanged
    {
        //private DataSet _testData;
        private Views.IAdminView _view;
        public ProjectAdminViewModel(Views.IAdminView view)
        {
            _view = view;

            this.PropertyChanged += new PropertyChangedEventHandler(ProjectAdminViewModel_PropertyChanged);

            //TODO Add can executes
            AddProjectCommand = new RelayCommand(AddProjectCommandExecute);
            AddTestCommand = new RelayCommand(AddTestCommandExecute);
            SaveCommand = new RelayCommand(SaveCommandExecute);

            Projects = new ObservableCollection<ProjectViewModel>();
            Tests = new ObservableCollection<Test>();

            AutoMapper.Mapper.CreateMap<Project, ProjectViewModel>();
            AutoMapper.Mapper.CreateMap<Test, TestViewModel>();
            AutoMapper.Mapper.CreateMap<ProjectViewModel, Project>();
            AutoMapper.Mapper.CreateMap<TestViewModel, Test>();

            var projects = RemoteTestRunner.BusinessLogic.Models.RtrServiceResolver.Service.GetProjects();
            MapProjectDtoToViewModel(projects);
        }

        void ProjectAdminViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            switch (e.PropertyName)
            {
                case "SelectedTest":
                    SelectedProject = GetParentProject(SelectedTest);
                    break;
                case "SelectedProject":
                    if (SelectedTest == null)
                    {
                        if (SelectedProject.Tests.Count == 0)
                        {
                            var newTest = new TestViewModel { Name = "New Test" };
                            SelectedProject.Tests.Add(newTest);
                        }
                        SelectedTest = SelectedProject.Tests[0];
                    }
                    else
                    {
                        var testParentProject = GetParentProject(SelectedTest);
                        if (!testParentProject.Equals(SelectedTest))
                        {
                            if (SelectedProject.Tests.Count == 0)
                            {
                                var newTest = new TestViewModel { Name = "New Test" };
                                SelectedProject.Tests.Add(newTest);
                            }
                            SelectedTest = SelectedProject.Tests[0];
                        }
                    }
                    break;
            }
        }

        private ProjectViewModel GetParentProject(TestViewModel test)
        {
            var projects = from p in Projects
                           from t in p.Tests
                           where t.Equals(SelectedTest)
                           select p;
            return projects.FirstOrDefault();
        }

        private void MapProjectDtoToViewModel(List<Project> projects)
        {
            Projects.Clear();
            foreach (var project in projects)
            {
                var mappedProject = AutoMapper.Mapper.Map<Project, ProjectViewModel>(project);
                Projects.Add(mappedProject);
            }
        }

        public ObservableCollection<ProjectViewModel> Projects { get; set; }

        #region Commands

        public ICommand AddProjectCommand { get; set; }
        public ICommand AddTestCommand { get; set; }
        public ICommand SaveCommand { get; set; }

        private void AddProjectCommandExecute(object obj)
        {
            var newProject = new ProjectViewModel { Name = "New Project" };
            var newTest = new TestViewModel { Name = "New Test" };
            newProject.Tests.Add(newTest);
            Projects.Add(newProject);
            SelectedTest = newTest;
        }

        private void AddTestCommandExecute(object obj)
        {
            SelectedProject.Tests.Add(new TestViewModel { Name = "New Test" });
            OnPropertyChanged("Projects");
        }

        private void SaveCommandExecute(object obj)
        {
            List<Project> projects = new List<Project>();

            foreach (var project in Projects)
            {
                var mappedProject = AutoMapper.Mapper.Map<ProjectViewModel, Project>(project);
                projects.Add(mappedProject);
            }
            RemoteTestRunner.BusinessLogic.Models.RtrServiceResolver.Service.SaveProjects(projects);
            _view.Close();
        }

        #endregion

        #region SelectedPath (INotifyPropertyChanged Property)
        private string _selectedPath;

        public string SelectedPath
        {
            get { return _selectedPath; }
            set
            {
                if (_selectedPath != value)
                {
                    _selectedPath = value;
                    OnPropertyChanged("SelectedPath");
                }
            }
        }
        #endregion

        #region SelectedTest (INotifyPropertyChanged Property)
        private TestViewModel _selectedTest;
        public TestViewModel SelectedTest
        {
            get { return _selectedTest; }
            set
            {
                if (_selectedTest != value)
                {
                    _selectedTest = value;
                    OnPropertyChanged("SelectedTest");
                }
            }
        }
        #endregion

        #region SelectedProject (INotifyPropertyChanged Property)
        private ProjectViewModel _selectedProject;
        public ProjectViewModel SelectedProject
        {
            get { return _selectedProject; }
            set
            {
                if (_selectedProject != value)
                {
                    _selectedProject = value;
                    OnPropertyChanged("SelectedProject");
                }
            }
        }
        #endregion

        #region Tests (INotifyPropertyChanged Property)
        private ObservableCollection<Test> _tests;
        public ObservableCollection<Test> Tests
        {
            get { return _tests; }
            set
            {
                if (_tests != value)
                {
                    _tests = value;
                    OnPropertyChanged("Tests");
                }
            }
        }
        #endregion

        #region IViewModelBase Members

        public void Start()
        {
            _view.SetRootDataContext(this);
            _view.ShowDialog();
        }

        public Views.IWpfViewBase View
        {
            get { return _view; }
        }

        #endregion

        #region INotifyPropertyChanged values

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

                switch (propertyName)
                {
                    case "SelectedPath":
                        break;
                    default:
                        break;
                }
            }
        }
        #endregion

    }
}
